package com.wordlearning.app.controller;

import com.wordlearning.app.service.TextToSpeechService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/tts")
public class TextToSpeechController {

    private static final Logger logger = LoggerFactory.getLogger(TextToSpeechController.class);
    
    private final TextToSpeechService textToSpeechService;
    
    @Value("${tts.default-format:WAV}")
    private String defaultFormat;
    
    @Value("${tts.supported-formats:[WAV,MP3]}")
    private List<String> supportedFormats;

    @Autowired
    public TextToSpeechController(TextToSpeechService textToSpeechService) {
        this.textToSpeechService = textToSpeechService;
    }

    @PostMapping("/synthesize")
    public ResponseEntity<byte[]> synthesizeText(
            @RequestParam("text") String text, 
            @RequestParam("userId") Long userId,
            @RequestParam(value = "format", required = false) String format) {
        try {
            logger.debug("Received TTS request for text: {}", text.substring(0, Math.min(20, text.length())));
            
            // 验证并确定音频格式
            String selectedFormat = validateAndSelectFormat(format);
            logger.debug("Selected audio format: {}", selectedFormat);
            
            // 调用服务执行TTS合成
            byte[] audioData = textToSpeechService.synthesizeText(text, userId);
            
            // 设置HTTP头部
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(getMediaTypeForFormat(selectedFormat));
            headers.setContentDispositionFormData("attachment", "speech." + selectedFormat.toLowerCase());
            
            return ResponseEntity.ok()
                    .headers(headers)
                    .body(audioData);
        } catch (IllegalArgumentException e) {
            logger.warn("Invalid TTS request: {}", e.getMessage());
            return ResponseEntity.badRequest().body(e.getMessage().getBytes());
        } catch (IOException e) {
            logger.error("Error during TTS synthesis", e);
            return ResponseEntity.status(500).body("Error during TTS synthesis".getBytes());
        }
    }
    
    /**
     * 验证并选择音频格式
     */
    private String validateAndSelectFormat(String format) {
        // 如果未指定格式，使用默认格式
        if (format == null || format.trim().isEmpty()) {
            return defaultFormat;
        }
        
        // 检查指定的格式是否受支持
        if (supportedFormats.stream().anyMatch(f -> f.equalsIgnoreCase(format))) {
            return format.toUpperCase();
        }
        
        // 如果指定的格式不受支持，抛出异常
        throw new IllegalArgumentException("Unsupported audio format: " + format + ". Supported formats: " + String.join(", ", supportedFormats));
    }
    
    /**
     * 根据音频格式获取对应的MIME类型
     */
    private MediaType getMediaTypeForFormat(String format) {
        switch (format.toUpperCase()) {
            case "MP3":
                return MediaType.parseMediaType("audio/mpeg");
            case "WAV":
                return MediaType.parseMediaType("audio/wav");
            default:
                return MediaType.APPLICATION_OCTET_STREAM;
        }
    }

    @GetMapping("/word/{word}")
    public ResponseEntity<byte[]> synthesizeWord(
            @PathVariable("word") String word, 
            @RequestParam("userId") Long userId,
            @RequestParam(value = "format", required = false) String format,
            @RequestParam(value = "voice", required = false) String voice) {
        try {
            logger.debug("Received TTS request for word : {}, voice: {}", word, voice);
            
            // 验证并确定音频格式
            String selectedFormat = validateAndSelectFormat(format);
            logger.debug("Selected audio format: {}", selectedFormat);
            
            // 根据是否提供voice参数选择不同的服务方法
            byte[] audioData;
            if (voice != null && !voice.trim().isEmpty()) {
                logger.debug("Using voice parameter from request: {}", voice);
                // 使用带voice参数的新方法
                audioData = textToSpeechService.synthesizeTextWithVoice(word, userId, voice);
            } else {
                logger.debug("No voice parameter provided, using default method");
                // 使用默认方法
                audioData = textToSpeechService.synthesizeText(word, userId);
            }
            
            // 设置HTTP头部
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(getMediaTypeForFormat(selectedFormat));
            headers.setContentDispositionFormData("attachment", "word_" + word + "." + selectedFormat.toLowerCase());
            
            return ResponseEntity.ok()
                    .headers(headers)
                    .body(audioData);
        } catch (IllegalArgumentException e) {
            logger.warn("Invalid word TTS request: {}", e.getMessage());
            return ResponseEntity.badRequest().body(e.getMessage().getBytes());
        } catch (IOException e) {
            logger.error("Error during word TTS synthesis", e);
            return ResponseEntity.status(500).body("Error during word TTS synthesis".getBytes());
        }
    }

    @GetMapping("/word-set/{wordSetId}")
    public ResponseEntity<byte[]> synthesizeWordSet(
            @PathVariable("wordSetId") Long wordSetId, 
            @RequestParam("userId") Long userId,
            @RequestParam(value = "format", required = false) String format) {
        try {
            logger.debug("Received TTS request for word set ID: {}", wordSetId);
            
            // 验证并确定音频格式
            String selectedFormat = validateAndSelectFormat(format);
            logger.debug("Selected audio format: {}", selectedFormat);
            
            // 调用服务执行词集的TTS合成
            byte[] audioData = textToSpeechService.synthesizeWordSet(wordSetId, userId);
            
            // 设置HTTP头部
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(getMediaTypeForFormat(selectedFormat));
            headers.setContentDispositionFormData("attachment", "wordset_" + wordSetId + "." + selectedFormat.toLowerCase());
            
            return ResponseEntity.ok()
                    .headers(headers)
                    .body(audioData);
        } catch (IllegalArgumentException e) {
            logger.warn("Invalid word set TTS request: {}", e.getMessage());
            return ResponseEntity.badRequest().body(e.getMessage().getBytes());
        } catch (IOException e) {
            logger.error("Error during word set TTS synthesis", e);
            return ResponseEntity.status(500).body("Error during word set TTS synthesis".getBytes());
        }
    }

    @GetMapping("/audio/{audioKey}")
    public ResponseEntity<Resource> getAudioResource(@PathVariable("audioKey") String audioKey) {
        try {
            logger.debug("Received request for audio resource with key: {}", audioKey);
            
            Resource resource = textToSpeechService.getAudioResource(audioKey);
            if (resource != null) {
                logger.debug("Audio resource found for key: {}", audioKey);
                return ResponseEntity.ok()
                        .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + audioKey + "." + defaultFormat.toLowerCase() + "\"")
                        .contentType(getMediaTypeForFormat(defaultFormat))
                        .body(resource);
            } else {
                logger.warn("Audio resource not found for key: {}", audioKey);
                return ResponseEntity.notFound().build();
            }
        } catch (Exception e) {
            logger.error("Error retrieving audio resource", e);
            return ResponseEntity.status(500).build();
        }
    }

    @GetMapping("/voices")
    public ResponseEntity<Map<String, String>> getAvailableVoices() {
        try {
            logger.debug("Received request for available voices");
            Map<String, String> voices = textToSpeechService.getAvailableVoices();
            return ResponseEntity.ok(voices);
        } catch (Exception e) {
            logger.error("Error retrieving available voices", e);
            return ResponseEntity.status(500).body(Collections.emptyMap());
        }
    }

    @PostMapping("/clear-cache")
    public ResponseEntity<HttpStatus> clearCache() {
        try {
            logger.debug("Received request to clear TTS cache");
            textToSpeechService.clearCache();
            logger.debug("TTS cache cleared successfully");
            return ResponseEntity.ok().build();
        } catch (Exception e) {
            logger.error("Error clearing TTS cache", e);
            return ResponseEntity.status(500).build();
        }
    }

}